package com.example.lcpractice.lc;

import com.example.lcpractice.datastructure.ListNode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 17. 电话号码的字母组合
 * 给定一个仅包含数字 2-9 的字符串，返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
 * 示例 1：
 * <p>
 * 输入：digits = "23"
 * 输出：["ad","ae","af","bd","be","bf","cd","ce","cf"]
 * 示例 2：
 * <p>
 * 输入：digits = ""
 * 输出：[]
 * 示例 3：
 * <p>
 * 输入：digits = "2"
 * 输出：["a","b","c"]
 *  
 * <p>
 * 提示：
 * <p>
 * 0 <= digits.length <= 4
 * digits[i] 是范围 ['2', '9'] 的一个数字。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/letter-combinations-of-a-phone-number
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class Lc17 {
    public static void main(String[] args) {
        ListNode list = ListNode.getSingleLinkedList();
        ListNode list2 = ListNode.getSingleLinkedList2();
        System.out.println(letterCombinations("23"));
    }

    HashMap<Character, List<Character>> phoneKeyMap = new HashMap<Character, List<Character>>() {
        {
            put('2', new ArrayList<Character>() {
                {
                    add('a');
                    add('b');
                    add('c');
                }
            });
            put('3', new ArrayList<Character>() {
                {
                    add('d');
                    add('e');
                    add('f');
                }
            });
            put('4', new ArrayList<Character>() {
                {
                    add('g');
                    add('h');
                    add('i');
                }
            });
            put('5', new ArrayList<Character>() {
                {
                    add('j');
                    add('k');
                    add('l');
                }
            });
            put('6', new ArrayList<Character>() {
                {
                    add('m');
                    add('n');
                    add('o');
                }
            });
            put('7', new ArrayList<Character>() {
                {
                    add('p');
                    add('q');
                    add('r');
                    add('s');
                }
            });
            put('8', new ArrayList<Character>() {
                {
                    add('t');
                    add('u');
                    add('v');
                }
            });
            put('9', new ArrayList<Character>() {
                {
                    add('w');
                    add('x');
                    add('y');
                    add('z');
                }
            });
        }
    };

    public List<String> letterCombinations22222(String digits) {
        List<List<Character>> list = new ArrayList<>();
        for (int i = 0; i < digits.length(); i++) {
            char c = digits.charAt(i);
            List<Character> characters = phoneKeyMap.get(c);
            list.add(characters);
        }
        for (int i = 0; i < list.size(); i++) {
            List<Character> characters = list.get(i);

        }
        return null;
    }
    // 数字到号码的映射
    private static String[] map = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

    // 路径
    private static StringBuilder sb = new StringBuilder();

    // 结果集
    private static List<String> res = new ArrayList<>();

    public static List<String> letterCombinations(String digits) {
        if(digits == null || digits.length() == 0) {
            return res;
        }
        backtrack(digits,0);
        return res;
    }

    // 回溯函数

    /**
     * "23"
     *  2-"abc" -"a"-暂存-开始回溯（index+1，取下一个按键）——
     *               没有达到长度——取index 3所在按键字符"def"-"d"-暂存-开始回溯（index+1，取下一个按键）——
     *                                                               -达到长度——加入结果"ad"到list-返回
     *                                                             暂存移去末尾字符
     *                                                        -"e"-暂存-开始回溯（index+1，取下一个按键）——
     *                                                                -达到长度——加入结果"ae"到list-返回
     *                                                             暂存移去末尾字符
     *                                                        -"f"-暂存-开始回溯（index+1，取下一个按键）——
     *                                                                -达到长度——加入结果"af"到list-返回
     *                                                             暂存移去末尾字符
     *
     * @param digits
     * @param index
     */
    private static void backtrack(String digits,int index) {
        if(sb.length() == digits.length()) {
            res.add(sb.toString());
            return;
        }
        // 取出拨号键对应的包含字符： 如2——{'a','b','c'}——"abc"
        String val = map[digits.charAt(index)-'2'];
        for(char ch:val.toCharArray()) {
            // 把每个字符添加到StringBuilder
            sb.append(ch);
            backtrack(digits,index+1);
            //每次回溯后删除上一次末尾字符
            sb.deleteCharAt(sb.length()-1);
        }
    }


}
